/**
 *  Copyright 2012 Seth Clark
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.pantsdown.engine.gl.renderer;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import com.pantsdown.engine.gl.Shader;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;

/**
 * @author Seth Clark
 *
 */
public class GLRenderer implements GLSurfaceView.Renderer {

	//Hnadle to the program obj
	private int mProgramObject;

	//Attribure locations
	private int mPositionLoc;
	private int mTexCoordLoc;

	//Sampler location
	private int mSamplerLoc;

	//Texture handle
	private int mTextureId;

	//Additional member variables
	private int mWidth;
	private int mHeight;
	private FloatBuffer mVertices;
	private ShortBuffer mIndices;

	private final float[] mVerticesData = {
			-0.5f, 0.5f, 0.0f, // Position 0
			0.0f, 0.0f, // TexCoord 0
			-0.5f, -0.5f, 0.0f, // Position 1
			0.0f, 1.0f, // TexCoord 1
			0.5f, -0.5f, 0.0f, // Position 2
			1.0f, 1.0f, // TexCoord 2
			0.5f, 0.5f, 0.0f, // Position 3
			1.0f, 0.0f // TexCoord 3
	};

	private final short[] mIndicesData = {
			0,1,2,0,2,3
	};


	public GLRenderer() {
		mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4)
				.order(ByteOrder.nativeOrder()).asFloatBuffer();
		mVertices.put(mVerticesData).position(0);
		mIndices = ByteBuffer.allocateDirect(mIndicesData.length * 2)
				.order(ByteOrder.nativeOrder()).asShortBuffer();
		mIndices.put(mIndicesData).position(0);
	}

	private static final String TAG = "GLRenderer";

	public void onDrawFrame(GL10 gl) {
		GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

	}

	public void onSurfaceChanged(GL10 gl, int width, int height) {
		GLES20.glViewport(0, 0, width, height);

	}

	public void onSurfaceCreated(GL10 gl, EGLConfig config) {

		String vShaderStr =
				"attribute vec4 a_position;   \n"
						+ "attribute vec2 a_texCoord;   \n"
						+ "varying vec2 v_texCoord;     \n"
						+ "void main()                  \n"
						+ "{                            \n"
						+ "   gl_Position = a_position; \n"
						+ "   v_texCoord = a_texCoord;  \n"
						+ "}                            \n";

		String fShaderStr = 
				"precision mediump float;                            \n"
						+ "varying vec2 v_texCoord;                            \n"
						+ "uniform sampler2D s_texture;                        \n"
						+ "void main()                                         \n"
						+ "{                                                   \n"
						+ "  gl_FragColor = texture2D( s_texture, v_texCoord );\n"
						+ "}                                                   \n";


		//load the shaders and get a linked program obj
		mProgramObject = Shader.loadProgram(vShaderStr, fShaderStr);
		
		//Get the attribute locations
		mPositionLoc = GLES20.glGetAttribLocation(mProgramObject, "a_position");
		mTexCoordLoc = GLES20.glGetAttribLocation(mProgramObject, "a_texCoord");
		
		//Get the sampler location
		mSamplerLoc = GLES20.glGetUniformLocation(mProgramObject, "s_texture");
		
		//Load the texture
		mTextureId = createTexture2D();
		
		GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);		
	}
	
	private int createTexture2D( )
    {
        // Texture object handle
        int[] textureId = new int[1];
        
        // 2x2 Image, 3 bytes per pixel (R, G, B)
        byte[] pixels = 
            {  
                (byte) 0xff,   0,   0, // Red
                0, (byte) 0xff,   0, // Green
                0,   0, (byte) 0xff, // Blue
                (byte) 0xff, (byte) 0xff,   0  // Yellow
            };
        ByteBuffer pixelBuffer = ByteBuffer.allocateDirect(4*3);
        pixelBuffer.put(pixels).position(0);

        // Use tightly packed data
        GLES20.glPixelStorei ( GLES20.GL_UNPACK_ALIGNMENT, 1 );

        //  Generate a texture object
        GLES20.glGenTextures ( 1, textureId, 0 );

        // Bind the texture object
        GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, textureId[0] );

        //  Load the texture
        GLES20.glTexImage2D ( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, 2, 2, 0, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, pixelBuffer );

        // Set the filtering mode
        GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST );
        GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST );

        return textureId[0];        
    }

}
